#include "coptional.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 1. 自定义结构体（带动态内存）
typedef struct {
    int id;
    char* name;  // 动态字符串
} User;

// 结构体复制函数（深度复制）
static void user_copy(const void* src, void* dest) {
    const User* s = (const User*)src;
    User* d = (User*)dest;
    d->id = s->id;
    if (s->name) {
        d->name = (char*)malloc(strlen(s->name) + 1);
        strcpy(d->name, s->name);
    } else {
        d->name = NULL;
    }
}

// 结构体销毁函数
static void user_destroy(void* data) {
    User* u = (User*)data;
    if (u->name) {
        free(u->name);
        u->name = NULL;
    }
}

// 2. 自定义枚举
typedef enum {
    MALE,
    FEMALE,
    OTHER
} Gender;

// 枚举复制函数
static void gender_copy(const void* src, void* dest) {
    *(Gender*)dest = *(const Gender*)src;
}

// 枚举销毁函数（无动态内存）
static void gender_destroy(void* data) {}

// 3. 自定义联合体
typedef union {
    int i;
    float f;
} Number;

// 联合体复制函数
static void number_copy(const void* src, void* dest) {
    *(Number*)dest = *(const Number*)src;
}

// 联合体销毁函数
static void number_destroy(void* data) {}

int main() {
    // 创建可选值对象
    COptional* opt = coptional_create();
    if (!opt) {
        printf("创建可选值失败\n");
        return 1;
    }

    // 测试1：内置类型（初始无值）
    printf("测试内置类型：\n");
    printf("初始状态 - 有值? %s\n", coptional_has_value(opt) ? "是" : "否");
    printf("无值时获取整数（默认-1）: %d\n", coptional_get_int(opt, -1));

    // 设置整数
    coptional_set_int(opt, 100);
    printf("设置整数后 - 类型: %d, 值: %d\n",
           coptional_get_type(opt),
           coptional_get_int(opt, -1));

    // 改为字符串
    coptional_set_str(opt, "hello optional");
    printf("改为字符串后 - 类型: %d, 值: %s\n",
           coptional_get_type(opt),
           coptional_get_str(opt, "默认"));


    // 测试2：自定义枚举
    printf("\n测试自定义枚举：\n");
    COptionalType gender_type = coptional_register_custom_type(
        sizeof(Gender), gender_copy, gender_destroy
    );
    Gender g = FEMALE;
    coptional_set_custom(opt, gender_type, &g);
    
    if (coptional_has_value(opt) && coptional_get_type(opt) == gender_type) {
        Gender get_g;
        coptional_get_custom(opt, &get_g);
        printf("枚举值: %d (FEMALE对应1)\n", get_g);
    }


    // 测试3：自定义联合体
    printf("\n测试自定义联合体：\n");
    COptionalType number_type = coptional_register_custom_type(
        sizeof(Number), number_copy, number_destroy
    );
    Number n;
    n.f = 3.14f;  // 存储float
    coptional_set_custom(opt, number_type, &n);
    
    if (coptional_has_value(opt)) {
        Number get_n;
        coptional_get_custom(opt, &get_n);
        printf("联合体float值: %f\n", get_n.f);
    }


    // 测试4：自定义结构体（带动态内存）
    printf("\n测试自定义结构体：\n");
    COptionalType user_type = coptional_register_custom_type(
        sizeof(User), user_copy, user_destroy
    );
    User u;
    u.id = 1;
    u.name = (char*)malloc(10);
    strcpy(u.name, "Alice");
    coptional_set_custom(opt, user_type, &u);
    
    if (coptional_has_value(opt)) {
        User get_u;
        coptional_get_custom(opt, &get_u);
        printf("结构体 - id: %d, name: %s\n", get_u.id, get_u.name);
        free(get_u.name);  // 释放复制出的字符串（因为user_copy做了深度复制）
    }
    free(u.name);  // 释放原始数据的字符串


    // 清理
    coptional_destroy(opt);
    return 0;
}